package ar.edu.unicen.exa.isistan.archassis.metadata;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ar.edu.unicen.exa.isistan.archassis.classreader.ClassReaderException;
import ar.edu.unicen.exa.isistan.archassis.classreader.IClassReader;
import ar.edu.unicen.exa.isistan.archassis.ia.api.db.JavaClass;
import ar.edu.unicen.exa.isistan.archassis.javatoxml.XMLClassReader;

/**
 * Esta clase se encarga de, como puede, obtener la lista de clases importadas
 * por una clase dada.
 * 
 * Esta funcionalidad sirve para dos cosas:
 * 1. Poder saber qué clase usa a cual.
 * 2. Poder obtener el nombre canónico de las clases usadas en otra clase.
 * 
 * @author sebastianperruolo@gmail.com
 *
 */
public class ClassResolver {
//	private static ClassResolver instance = null;
	
	private List<File> javafiles;
	
	private Map<String, JavaClass> classMetadata;
	
	private List<String> srcFolders;
	
	
	public ClassResolver(File srcFolder) { 
		javafiles = new ArrayList<File>();
		
		srcFolders = new ArrayList<String>();
		
		classMetadata = new HashMap<String, JavaClass>();
		loadInfo(srcFolder);
	}
	
//	public static ClassResolver getInstance() {
//		if (instance == null) {
//			instance = new ClassResolver();
//		}
//		return instance;
//	}

	private void loadInfo(File srcFolder) {
//		javafilesV0.clear();
//		javafilesV1.clear();
//		
//		classMetadataV0.clear();
//		classMetadataV1.clear();
//		
//		srcFolders.clear();
		
		scan(srcFolder, javafiles);
		
		//IClassReader classReader = new XMLClassReader();
		
		//classMetadataV0.put(classMetadata.getAbsoluteName(), classMetadata);
		
		
		parse(srcFolder, javafiles, classMetadata, srcFolders);
	}
	
	private static void parse(File baseDir, List<File> javaFiles, Map<String, JavaClass> classMetadataMap, List<String> srcFolders) {
		IClassReader classReader = new XMLClassReader();
		
		for (File javaFile : javaFiles) {
			try {
				JavaClass javaClass = classReader.loadFrom(javaFile);
				if (javaClass == null) {
					continue;
				}
				//System.out.println("classMetadata: " + javaClass.getNombre());
				classMetadataMap.put(javaClass.getNombre(), javaClass);
				String srcFolder = trim(baseDir, javaFile, javaClass.getNombre());
				javaClass.setSRCFolder(srcFolder);
				
				if (! srcFolders.contains(srcFolder)) {
					srcFolders.add(srcFolder);
				}
//			} catch (ClassReaderException e) {
//				System.out.println(e.getMessage());
//				e.printStackTrace();
			} catch (Exception e) {
				System.out.println(e.getMessage());
				e.printStackTrace();
			}
		}
		
		
	}
	
	private static String trim(File baseDir, File file, String className) {
		//String filePath = file.getAbsolutePath();
		String basePath = baseDir.getAbsolutePath().replace('\\', '/');
		String result = file.getAbsolutePath().replace('\\', '/');
		String classFile = className.replace('.', '/') + ".java";
//		System.out.println(basePath);
//		System.out.println(result);
//		System.out.println(classFile);
		
		if (result.startsWith(basePath)) {
			result = result.replaceFirst(basePath, "");
		}
//		System.out.println("1=" + result);
		if (result.endsWith(classFile)) {
			result = result.replaceFirst(classFile, "");
		}
//		System.out.println("2=" + result);
		if (result.startsWith("/")) {
			result = result.replaceFirst("/", "");
		}
//		System.out.println("3=" + result);
		
		if (result.endsWith("/")) {
			result = result.substring(0,result.length()-1);
		}
//		System.out.println("4=" + result);
		
		
//		System.out.println("-------------------");
//		
//		System.out.println(basePath);
//		System.out.println(result);
//		System.out.println(classFile);
//		System.out.println(file.getAbsolutePath());
//		
//		System.out.println("-------------------");
		return result;
	}
	public static void main(String[] args) {
		File javaFile = new File("/home/kache/apps/workspaces/workspace-tesis/SVNHumanDiff/tmp/svn.codespot.com_a_eclipselabs.org_svn-human-diff_trunk/rev_91/ar.edu.unicen.exa.isistan.plugin.menu/src/ar/edu/unicen/exa/isistan/plugin/menu/Activator.java");
		File baseDir = new File("/home/kache/apps/workspaces/workspace-tesis/SVNHumanDiff/tmp/svn.codespot.com_a_eclipselabs.org_svn-human-diff_trunk/rev_91/");
		String className = "ar.edu.unicen.exa.isistan.plugin.menu.Activator";
		System.out.println(trim(baseDir, javaFile, className));
		//File srcFolderV0 = new File("/home/kache/apps/workspaces/workspace-tesis/SVNHumanDiff/tmp/svn.codespot.com_a_eclipselabs.org_logviewer_trunk/rev_60/de.anbos.eclipse.logviewer.plugin/src/de/anbos/eclipse/logviewer/plugin/viewer/rule");
		//File srcFolderV1 = new File("/home/kache/apps/workspaces/workspace-tesis/SVNHumanDiff/tmp/svn.codespot.com_a_eclipselabs.org_logviewer_trunk/rev_1/de.anbos.eclipse.logviewer.plugin/src/de/anbos/eclipse/logviewer/plugin/viewer/rule");

		//ClassResolver.getInstance().loadInfo(srcFolderV0, srcFolderV1);
		//parse("/home/kache/apps/workspaces/workspace-tesis/SVNHumanDiff/tmp/JAVA2XML.xml", new HashMap<String, List<String>>());
	}

	private static void scan(File srcFolder, List<File> javaFiles) {
		if (srcFolder.isFile()) {
			addFile(srcFolder, javaFiles);
			return;
		}
		if (srcFolder.isDirectory()) {
			File[] list = srcFolder.listFiles();
			for (File aFile : list) {
				scan(aFile, javaFiles);
			}
		}
	}

	private static void addFile(File aFile, List<File> javaFiles) {
		if (aFile.getAbsolutePath().endsWith(".java")) {
			javaFiles.add(aFile);
		}
	}

	public Collection<JavaClass> getClassMetadata() {
		 return classMetadata.values();
	}

	public JavaClass getClassMetadata(String className) {
		return classMetadata.get(className);
	}
	
	public List<String> getSrcFolders() {
		return srcFolders;
	}
	
}
